package com.lcf.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.lcf.framework.exception.SysException;
import com.lcf.framework.vo.PageVO;
import com.lcf.system.dao.SysRoleDao;
import com.lcf.system.dto.role.SysRoleDTO;
import com.lcf.system.entity.SysRole;
import com.lcf.system.entity.SysRoleMenu;
import com.lcf.system.entity.SysUserRole;
import com.lcf.system.enums.SysRoleEnum;
import com.lcf.system.manager.CacheManager;
import com.lcf.system.manager.SysRoleManager;
import com.lcf.system.query.role.SysRolePageQuery;
import com.lcf.system.service.SysRoleService;
import com.lcf.system.vo.role.SysRoleVO;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.List;

/**
 * 角色(SysRole)表服务实现类
 *
 * @author lcf
 * @since 2025-02-25 12:28:33
 */
@Service("sysRoleService")
public class SysRoleServiceImpl extends ServiceImpl<SysRoleDao, SysRole> implements SysRoleService {
    @Resource
    private SysRoleManager sysRoleManager;
    @Resource
    private CacheManager cacheManager;

    @Override
    public void add(SysRoleDTO dto) {
        sysRoleManager.checkExist(null, dto);

        BeanUtil.copyProperties(dto, SysRole.class).insert();
    }

    @Override
    public void update(long id, SysRoleDTO dto) {
        SysRole exist = sysRoleManager.checkId(id);
        if (SysRoleEnum.isSysRole(exist.getRoleCode())) {
            throw new SysException("内置角色不允许修改");
        }

        sysRoleManager.checkExist(id, dto);

        SysRole sysRole = BeanUtil.copyProperties(dto, SysRole.class);
        sysRole.setId(id);
        sysRole.updateById();

        // 删除角色缓存
        cacheManager.delRoleCache(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(long id) {
        SysRole exist = sysRoleManager.checkId(id);

        if (SysRoleEnum.isSysRole(exist.getRoleCode())) {
            throw new SysException("内置角色不允许修改");
        }

        //检查角色是否已被使用
        if(Db.lambdaQuery(SysUserRole.class).eq(SysUserRole::getRoleId, id).exists()) {
            throw new SysException("角色已使用");
        }

        removeById(id);
        //删除角色菜单关联数据
        Db.lambdaUpdate(SysRoleMenu.class).eq(SysRoleMenu::getRoleId, id).remove();
        //删除用户角色关联数据
        Db.lambdaUpdate(SysUserRole.class).eq(SysUserRole::getRoleId, id).remove();

        // 删除角色缓存
        cacheManager.delRoleCache(id);
    }

    @Override
    public PageVO<SysRoleVO> getPage(SysRolePageQuery query) {
        Page<SysRole> page = lambdaQuery()
                .like(StringUtils.isNotBlank(query.getRoleName()), SysRole::getRoleName, query.getRoleName())
                .page(query.toPage());

        return new PageVO<>(page, SysRoleVO.class);
    }

    @Override
    public List<SysRoleVO> getAll() {
        List<SysRole> list = lambdaQuery().list();
        if (CollectionUtil.isNotEmpty(list)) {
            return BeanUtil.copyToList(list, SysRoleVO.class);
        }

        return Collections.emptyList();
    }

    @Override
    public SysRoleVO getDetail(long id) {
        SysRole role = getById(id);

        return BeanUtil.copyProperties(role, SysRoleVO.class);
    }
}

